package cn.yshujia.aop;

import cn.yshujia.domain.vo.ApiVO;
import cn.yshujia.utils.RequestUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;


/**
 * @author YShuJia
 * @description 日志记录
 * @create 2024/4/23
 */

@Slf4j
@Aspect
@Component
public class LogAspect {
	
	@AfterReturning (value = "execution (* cn.yshujia.controller..*.*(..))", returning = "methodResult")
	public void doAfterReturning(JoinPoint joinPoint, Object methodResult) {
		doAfter(joinPoint, methodResult);
	}
	
	@Async ("Task")
	public void doAfter(JoinPoint joinPoint, Object methodResult) {
		HttpServletRequest request = RequestUtils.getReq();
		// GET请求不记录日志 返回类型不是 ApiVO不记录
		if ("GET".equals(request.getMethod()) || !(methodResult instanceof ApiVO<?> apiVO)) {
			return;
		}
		String url = request.getServletPath();
		String className = joinPoint.getTarget().getClass().getName();
		MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
		StringBuilder param = new StringBuilder();
		try {
			ParameterNameDiscoverer parameterName = new DefaultParameterNameDiscoverer();
			// 获取参数名集合
			String[] arrayOfString = parameterName.getParameterNames(methodSignature.getMethod());
			// 获取参数值
			Object[] args = joinPoint.getArgs();
			if (args != null && arrayOfString != null && args.length == arrayOfString.length){
				for (int i = 0; i < arrayOfString.length; i++) {
					if (arrayOfString[i].contains("pass")) {
						param.append(arrayOfString[i]).append("=").append("******");
					} else {
						param.append(arrayOfString[i]).append("=").append(args[i]);
					}
				}
				}
		} catch (Exception e) {
			log.error("获取参数: {}", e.getLocalizedMessage());
		} finally {
			if (apiVO.getCode() >= 300 || apiVO.getCode() < 200) {
				log.error("执行的用户：{}\n执行的类名：{}\n执行的接口：{}\n执行的数据：{}\n执行的结果：{}\n" +
								"<<--------------------------------------------------------------------------------------->>",
						RequestUtils.getIp(), className, url, param, apiVO);
			} else {
				log.info("执行的用户：{}\n执行的类名：{}\n执行的接口：{}\n执行的数据：{}\n执行的结果：{}\n" +
								"<<--------------------------------------------------------------------------------------->>",
						RequestUtils.getIp(), className, url, param, apiVO);
			}
		}
	}
}